﻿// Copyright: 2012
// Author: Minh Vu - YoungJ
// File: Class1.cs - WpfEncryption - WpfEncryption
// Time: 12:35 AM 05/28/2012

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace WpfEncryption.Converter
{
    public class VisiableConverter : IValueConverter
    {
        #region Implementation of IValueConverter

        /// <summary>
        /// Modifies the source data before passing it to the target for display in the UI.
        /// </summary>
        /// <returns>
        /// The value to be passed to the target dependency property.
        /// </returns>
        /// <param name="value">The source data being passed to the target.</param><param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param><param name="parameter">An optional parameter to be used in the converter logic.</param><param name="culture">The culture of the conversion.</param>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var isVisibale = (bool)value;
            if (IsVisibilityInverted(parameter))
                isVisibale = !isVisibale;
            return isVisibale ? Visibility.Visible : Visibility.Collapsed;

        }

        /// <summary>
        /// Modifies the target data before passing it to the source object.  This method is called only in <see cref="F:System.Windows.Data.BindingMode.TwoWay"/> bindings.
        /// </summary>
        /// <returns>
        /// The value to be passed to the source object.
        /// </returns>
        /// <param name="value">The target data being passed to the source.</param><param name="targetType">The <see cref="T:System.Type"/> of data expected by the source object.</param><param name="parameter">An optional parameter to be used in the converter logic.</param><param name="culture">The culture of the conversion.</param>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var isVisible = ((Visibility)value == Visibility.Visible);

            // If visibility is inverted by the converter parameter, then invert our value
            if (IsVisibilityInverted(parameter))
                isVisible = !isVisible;

            return isVisible;
        }

        #endregion


        /// <summary>
        /// Determine the visibility mode based on a converter parameter.  This parameter is of type Visibility,
        /// and specifies what visibility value to return when the boolean value is true.
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private static Visibility GetVisibilityMode(object parameter)
        {
            // Default to Visible
            var mode = Visibility.Visible;

            // If a parameter is specified, then we'll try to understand it as a Visibility value
            if (parameter != null)
            {
                // If it's already a Visibility value, then just use it
                if (parameter is Visibility)
                {
                    mode = (Visibility)parameter;
                }
                else
                {
                    // Let's try to parse the parameter as a Visibility value, throwing an exception when the parsing fails
                    try
                    {
                        mode = (Visibility)Enum.Parse(typeof(Visibility), parameter.ToString(), true);
                    }
                    catch (FormatException e)
                    {
                        throw new FormatException("Invalid Visibility specified as the ConverterParameter.  Use Visible or Collapsed.", e);
                    }
                }
            }

            // Return the detected mode
            return mode;
        }




        /// <summary>
        /// Determine whether or not visibility is inverted based on a converter parameter.
        /// When the parameter is specified as Collapsed, that means that when the boolean value
        /// is true, we should return Collapsed, which is inverted.
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private static bool IsVisibilityInverted(object parameter)
        {
            return (GetVisibilityMode(parameter) == Visibility.Collapsed);
        }
    }
}